package fiuba.algo3.vista;

import java.util.ArrayList;
import java.util.Scanner;

import fiuba.algo3.Ciudad;
import fiuba.algo3.Edificio;
import fiuba.algo3.Juego;
import fiuba.algo3.OrdenDeArresto;
import fiuba.algo3.control.Controlador;


public class VistaConsola {
	Controlador control;
	Juego modelo;

	public VistaConsola(Controlador control) {
		this.control = control;
	}
	
	public void setModelo(Juego modelo) {
		this.modelo = modelo;
	}

	private void printSeparador(){
		System.out.println("--------------------------------------------------------------------------------");
	}
	
	public void mensajeProblemaInesperado(){
		System.out.println("*** Se ha producido un error interno. El programa debe terminar.");
	}
	
	public void bienvenida() throws Exception{
		this.printSeparador();
		System.out.println("Where in the world is CARMEN SANDIEGO");
		this.printSeparador();
		System.out.println("Identifiquese: ");
		@SuppressWarnings("resource")
		Scanner scanner = new Scanner(System.in);
		String nombre = scanner.next();

		control.leerEntradaAgente(nombre);	
	}
	
	public int validarEntradaUsuario(String entrada, int inicioRango, int finRango){
		try{
			int entrada_int = Integer.parseInt(entrada);
			if (entrada_int >= inicioRango && entrada_int <= finRango)
				return entrada_int;
		}
		catch (Exception e)
		{
			return -1;
		}
		return -1;
	}

	
	public int menuDeOpciones() throws Exception{
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{
			this.printSeparador();
			System.out.println("Ingrese el numero de la opcion deseada: ");
			System.out.println("1 Viajar");
			System.out.println("2 Visitar edificio");
			System.out.println("3 Actualizar orden de arresto");
			System.out.println("4 Guardar juego");
			System.out.println("5 Instrucciones del juego");
			System.out.println("0 Salir");
			
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next();
			int opc = this.validarEntradaUsuario(respuesta, 0, 5);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}

	public void pistaSexoLadron(){
		this.printSeparador();
		System.out.println("*** Ha ocurrido un delito! Escuche con atencion!\n"
		+ "*** Objeto robado: " + modelo.getCaso().getObjetoRobado().getNombre());
		if (modelo.getLadron().esHombre())
			System.out.println("*** Los testigos afirman que vieron a un hombre escapando del lugar!");
		else
			System.out.println("*** Los testigos afirman que vieron a una mujer escapando del lugar!");
		System.out.println("*** A trabajar! Tiene 134 horas para resolver el caso.");
	}
	
	public void estadoDelJuego() {
		this.printSeparador();
		VistaPolicia policia = new VistaPolicia(modelo.getPolicia());
		VistaCiudad ciudad = new VistaCiudad(modelo.getPolicia().getCiudadActual());
		System.out.print("Agente: ");
		policia.printNombre();
		System.out.print("Grado actual: ");
		policia.printGrado();
		System.out.print("Ciudad actual: ");
		ciudad.print();
		System.out.print("Tiempo restante: ");
		policia.printTiempoRestante();		
		}
	
	public int menuSeguirJugando(){
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{	
			System.out.println("Desea continuar resolviendo casos?: ");
			System.out.println("1 Si");
			System.out.println("2 No");
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next();
			int opc = this.validarEntradaUsuario(respuesta, 1, 2);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}
	
	public int menuDeseaSalir() throws Exception{
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{	
			System.out.println("Esta seguro que desea salir?");
			System.out.println("1 Salir");
			System.out.println("2 Salir y guardar");
			System.out.println("0 Volver al juego");
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next();
			int opc = this.validarEntradaUsuario(respuesta, 0, 2);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}
	
	public int menuCiudadesParaViajar(ArrayList<Ciudad> ciudades) throws Exception{
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{
			this.printSeparador();
			System.out.println("Ingrese el numero de la opcion para viajar a esa ciudad:");
			for ( int i=0; i<ciudades.size(); i++) {
				Ciudad ciudad = ciudades.get(i);
				VistaCiudad vistaCiudad = new VistaCiudad(ciudad);
				System.out.print(i + 1 + " ");	
				vistaCiudad.print();
			}
			
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next();
			int opc = this.validarEntradaUsuario(respuesta, 1, 3);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}
	
	public int menuEdificiosParaVisitar(ArrayList<Edificio> edificios) throws Exception{
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{
			this.printSeparador();
			for ( int i=0; i<edificios.size(); i++) {
				Edificio edificio = edificios.get(i);
				VistaEdificio vistaEdificio = new VistaEdificio(edificio);
				System.out.print(i + 1 + " ");	
				vistaEdificio.print();
			}
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next();
			int opc = this.validarEntradaUsuario(respuesta, 1, 3);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}
	
	public int menuOrdenDeArresto() throws Exception{
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{
			this.mostrarOrdenDeArresto(modelo.getPolicia().getOrdenDeArresto());
			System.out.println("Ingrese el numero de la opcion a modificar: ");
			System.out.println("1 Sexo");
			System.out.println("2 Hobby");
			System.out.println("3 Cabello");
			System.out.println("4 Senia");
			System.out.println("5 Auto");
			System.out.println("6 Validar orden de arresto");
			System.out.println("0 Volver a opciones");
			
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next();
			int opc = this.validarEntradaUsuario(respuesta, 0, 6);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}
	
	public int modificarSexo() throws Exception {
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{
			System.out.println("Ingrese numero de opcion: ");
			System.out.println("0 Ninguno");
			System.out.println("1 Masculino");
			System.out.println("2 Femenino");
			
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next(); 
			int opc = this.validarEntradaUsuario(respuesta, 0, 2);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}
	
	public int modificarHobby() throws Exception {
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{
			System.out.println("Ingrese numero de opcion: ");
			System.out.println("0 Ninguno");
			System.out.println("1 Alpinismo");
			System.out.println("2 Croquet");
			System.out.println("3 Tenis");
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next(); 
			int opc = this.validarEntradaUsuario(respuesta, 0, 3);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}
	
	public int modificarCabello() throws Exception {
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{
			System.out.println("Ingrese numero de opcion: ");
			System.out.println("0 Ninguno");
			System.out.println("1 Negro");
			System.out.println("2 Rojo");
			System.out.println("3 Castanio");
			System.out.println("4 Rubio");
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next(); 
			int opc = this.validarEntradaUsuario(respuesta, 0, 4);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}

	public int modificarSenia() throws Exception {
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{
			System.out.println("Ingrese numero de opcion: ");
			System.out.println("0 Ninguno");
			System.out.println("1 Anillo");
			System.out.println("2 Tatuaje");
			System.out.println("3 Joyas");		
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next(); 
			int opc = this.validarEntradaUsuario(respuesta, 0, 3);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}

	public int modificarAuto() throws Exception {
		boolean ingresoCorrecto = false;
		int opcionElegida = -1;
		while (!ingresoCorrecto)
		{
			System.out.println("Ingrese numero de opcion: ");
			System.out.println("0 Ninguno");
			System.out.println("1 Moto");
			System.out.println("2 Descapotable");
			System.out.println("3 Limusina");
			@SuppressWarnings("resource")
			Scanner scanner = new Scanner(System.in);
			String respuesta = scanner.next(); 
			int opc = this.validarEntradaUsuario(respuesta, 0, 3);
			if (opc != -1)
			{
				ingresoCorrecto = true;
				opcionElegida = opc;
			}
			else
				this.opcionInvalida();
		}
		return opcionElegida;
	}
	
	public void mostrarOrdenDeArresto(OrdenDeArresto orden){
		VistaOrdenDeArresto vistaOrden = new VistaOrdenDeArresto(orden);
		vistaOrden.print();
	}
	
	public void mostrarValidacionOrdenDeArresto(VistaOrdenDeArresto orden, boolean b){
		System.out.println();
		if (b){
			System.out.println("*** Su orden ha sido aprobada."); 
			System.out.print("*** El sospechoso es: ");
			orden.printSospechoso();
		}
		else{
			System.out.println("*** La orden no pudo ser aprobada, busque mas informacion.");
		}
	}
	
	public void mostrarResultadoLadronAtrapado(boolean atrapado, boolean orden){
		printSeparador();
		VistaPolicia policia = new VistaPolicia(modelo.getPolicia());
		if (atrapado)
			System.out.println("*** Enhorabuena! Has atrapado al ladron!\n" +
				"*** Felicitaciones :D");
		else if (!atrapado && !orden)
			System.out.println("*** Usted no tiene orden de arresto!\n" + 
					"*** El ladron ha escapado! :@");
		else
			System.out.println("*** Su orden de arresto es incorrecta!\n" +
					"*** El ladron ha escapado! :@");
		
		System.out.println("Resultados del juego:");
		System.out.println("Tiempo requerido para atrapar al ladron: " + (134 - modelo.getPolicia().getTiempoRestante()) + " horas.");
		System.out.print("Cantidad de ladrones atrapados: ");
		policia.printArrestos();
		System.out.print("Grado actual: ");
		policia.printGrado();
	}
	
	public void mostrarResultadoTiempoCumplido(){
		System.out.println();
		
		System.out.println("*** :(");
		System.out.println("*** Se ha quedado sin tiempo! Mas suerte la proxima!");
		System.out.println();
	}
	
	public void mensajeBienvenida(boolean esNuevo){
		VistaPolicia policia = new VistaPolicia( this.modelo.getPolicia() );
		if (esNuevo)
			System.out.print("*** Bienvenido, agente ");
		else
            System.out.print("*** Bienvenido de nuevo, agente ");
		policia.printNombre();
	}
	
	public void mensajeDespedida() {
		VistaPolicia policia = new VistaPolicia( this.modelo.getPolicia() );
		System.out.print("*** Hasta la proxima, agente ");
		policia.printNombre();	
	}
	
	public void mensajeGuardarExito(){
		System.out.println("*** La partida fue guardada con exito.");
	}
	
	public void mensajeGuardarError(){
		System.out.println("*** Ha ocurrido un error al guardar la partida.");
	}
	
	public void mensajeUltimaCiudad() {
		System.out.println("*** No hay mas ciudades disponibles.");		
	}
	
	public void opcionInvalida(){
		System.out.println("*** Opcion invalida.");
	}

}
